package com.gitee.wsl.text.buffer

import androidx.compose.ui.text.TextRange
import com.gitee.wsl.text.buffer.storage.GetCharsTrait

/*
@JvmInline
value class TextRange private constructor(private val packed: Long) {
    constructor(index: Int) : this(index, index)
    constructor(startInclusive: Int, endExclusive: Int) : this(
        packInts(startInclusive, endExclusive)
    )

    val start: Int get() = unpackIntA(packed)
    val end: Int get() = unpackIntB(packed)

    val length: Int get() = end - start

    override fun toString(): String =
        "TextRange(startInclusive=$start, endExclusive=$end)"

    companion object {
        val Zero = TextRange(0)
        val Unspecified = TextRange(-1)
    }
}

@Suppress("NOTHING_TO_INLINE")
private inline fun packInts(a: Int, b: Int): Long {
    require(a <= b) { "Expected $a ≤ $b" }
    return a.toLong().shl(32) or (b.toLong() and 0xFFFFFFFF)
}

@Suppress("NOTHING_TO_INLINE")
private inline fun unpackIntA(value: Long): Int = value.shr(32).toInt()

@Suppress("NOTHING_TO_INLINE")
private inline fun unpackIntB(value: Long): Int = value.and(0xFFFFFFFF).toInt()
*/


val TextRange.Companion.Unspecified get() = TextRange(-1)

fun StringBuilder.replace(
    range: TextRange,
    replacement: Char,
    sourceMark: Any?
) {
    @Suppress("NAME_SHADOWING")
    val range = if (range == TextRange.Unspecified) TextRange(0, length) else range
    if (range.length == 0) {
        insert(range.start, replacement)
    } else {
        replaceRange(range.start, range.end, replacement.toString())
    }
}

fun <T> StringBuilder.replace(
    range: TextRange,
    replacement: T,
    replacementRange: TextRange,
    sourceMark: Any?,
    getCharsTrait: GetCharsTrait<T>
) {
    @Suppress("NAME_SHADOWING")
    val range = if (range == TextRange.Unspecified) TextRange(0, length) else range

    if (replacementRange.length == 0) {
        replaceRange(range.start, range.end, "")
    } else {
        val chars = CharArray(replacementRange.length)
        getCharsTrait.getChars(
            replacement,
            replacementRange.start,
            replacementRange.end,
            chars,
            0
        )
        val replacementString = chars.concatToString()

        if (range.length == 0) {
            insert(range.start, replacementString)
        } else {
            replaceRange(range.start, range.end, replacementString)
        }
    }
}